import * as bull from '@midwayjs/bull'
import * as bullBoard from '@midwayjs/bull-board'
import * as captcha from '@midwayjs/captcha'
import {
  ALL,
  App,
  Config,
  Configuration,
  IMidwayContainer,
  Logger,
  MidwayConfig
} from '@midwayjs/core'
import * as jwt from '@midwayjs/jwt'
import * as koa from '@midwayjs/koa'
import { ILogger } from '@midwayjs/logger'
import * as redis from '@midwayjs/redis'
import * as swagger from '@midwayjs/swagger'
import * as orm from '@midwayjs/typeorm'
import * as upload from '@midwayjs/upload'
import * as validate from '@midwayjs/validate'
import * as cache from '@ttou/midway-cache'
import * as excel from '@ttou/midway-excel'

import { DefaultConfig, LocalConfig, ProdConfig } from './config'
import { DefaultErrorFilter, ValidateErrorFilter } from './filter'
import { AuthorizationGuard } from './guard'
import {
  AuthenticationMiddleware,
  LoggingMiddleware,
  ResponseMiddleware
} from './middleware'

@Configuration({
  imports: [
    koa,
    validate,
    jwt,
    orm,
    redis,
    upload,
    bull,
    bullBoard,
    captcha,
    swagger,
    excel,
    cache
  ],
  importConfigs: [
    {
      default: DefaultConfig,
      local: LocalConfig,
      prod: ProdConfig
    }
  ]
})
export class ContainerLifeCycle {
  @App()
  app: koa.Application

  @Config(ALL)
  config: MidwayConfig

  @Logger()
  logger: ILogger

  async onReady(container: IMidwayContainer) {
    // 添加中间件
    this.app.useMiddleware([
      LoggingMiddleware,
      AuthenticationMiddleware,
      ResponseMiddleware
    ])

    // 添加过滤器
    this.app.useFilter([ValidateErrorFilter, DefaultErrorFilter])

    // 添加守卫
    this.app.useGuard([AuthorizationGuard])
  }

  async onServerReady(container: IMidwayContainer) {
    // 打印一些信息
    const port = this.config.koa.port
    const protocol = this.config.koa.cert ? 'https' : 'http'
    const bullPath = this.config.bullBoard.basePath
    const swaggerPath = this.config.swagger.swaggerPath
    const basePath = `${protocol}://127.0.0.1:${port}`

    console.log('\n')
    this.logger.info(`[midway:bull] Bull Board: ${basePath}${bullPath}`)
    this.logger.info(
      `[midway:swagger] Swagger UI: ${basePath}${swaggerPath}/index.html`
    )
    this.logger.info(
      `[midway:swagger] Swagger JSON: ${basePath}${swaggerPath}/index.json`
    )
    console.log('\n')
  }
}
